﻿// --------------------------------
// <copyright file="HUD.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Jakub Tkadleček, Lukáš Molnár</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>9. 12. 2011 7:41:47</date>

// <summary>
//
// </summary>
// --------------------------------

using System.Linq;
using FITClub.Episode1.Configuration;
using FITClub.TextureMenu;
using Microsoft.Xna.Framework;
using System;

namespace FITClub.Episode1.Components
{
    /// <summary>
    /// Manages drawing of Head-Up Display
    /// </summary>
    public class HUD : DrawableGameComponent
    {
        private Menu hud;
        private GameFITClub game;

        private Label labelTime;

        public Label[] LabelPlayers { get; private set; }

        public Label[] ScorePlayers { get; private set; }

        public ImageItem[] PowerupImages { get; private set; }

        public ImageItem[] Icons { get; private set; }

        private ModelPreset powerUpTextures;

        private int activePlayers;

        private Label[] helpLabelsJoistick;
        private Label[] helpLabelsGamepad;
        private Checkbox chBoxTouch;

        public string Time
        {
            get { return labelTime.Text; }
            set { this.labelTime.Text = value; }
        }

        private TimeSpan elapsedTime;
        private bool showHelp;

        /// <summary>
        /// Konstruktor, alokace kontrolek
        /// </summary>
        /// <param name="game">Odkaz na probihajici hru</param>
        /// <param name="hudMenu">Odkaz na menu z menu managera</param>
        public HUD(GameFITClub game, Menu hudMenu)
            : base(game)
        {
            this.hud = hudMenu;
            this.game = game;
            this.DrawOrder = int.MaxValue;
            this.LabelPlayers = new Label[game.MaxPlayers];
            this.ScorePlayers = new Label[game.MaxPlayers];
            this.PowerupImages = new ImageItem[game.MaxPlayers];
            this.Icons = new ImageItem[game.MaxPlayers];

            this.labelTime = hud.InactiveItems.Single((ADisplayable ad) => ad is Label && ad.Name == "labelTime") as Label;

            this.activePlayers = this.game.PlayerCount;//int.Parse(this.game.ListPlayerCount.SelectedValue);
            for (int i = 0; i < game.MaxPlayers; i++)
            {
                this.LabelPlayers[i] = MenuManager.Current.Displayables["labelPlayer" + (i + 1)] as Label; //hud.InactiveItems.Single((ADisplayable ad) => ad is Label && ad.Name == "labelPlayer"+(i+1)) as Label;
                this.ScorePlayers[i] = MenuManager.Current.Displayables["scorePlayer" + (i + 1)] as Label;
                this.PowerupImages[i] = MenuManager.Current.Displayables["imagePowerUp" + (i + 1)] as ImageItem;
                this.Icons[i] = MenuManager.Current.Displayables["icon" + (i + 1)] as ImageItem;
            }
            this.helpLabelsJoistick = new Label[3];
            for (int i = 0; i < this.helpLabelsJoistick.Length; i++)
            {
                this.helpLabelsJoistick[i] = MenuManager.Current.Displayables["labelHUD" + i] as Label;
            }
            this.elapsedTime = new TimeSpan(0);
            this.chBoxTouch = MenuManager.Current.Displayables["checkBoxTouch"] as Checkbox;
            chBoxTouch.CheckedChanged += new Action<Checkbox>(chBoxTouch_CheckedChanged);
            this.chBoxTouch_CheckedChanged(this.chBoxTouch);
            this.showHelp = chBoxTouch.IsChecked == false && FITClubSettings.Current.ExitCount < 5;

        }

        private void chBoxTouch_CheckedChanged(Checkbox obj)
        {
            if (this.showHelp)
            {
                for (int i = 0; i < this.helpLabelsJoistick.Length; i++)
                {
                    this.helpLabelsJoistick[i].Visible = obj.IsChecked == false;
                }
            }
        }

        /// <summary>
        /// Inicialiazace vsech potrebnych komponent v tomto menu
        /// </summary>
        public override void Initialize()
        {
            //variables for powerUp images
            int width = 50; //override of image size
            int dx = 25;    //override of image X position

            activePlayers = this.game.PlayerCount;
            Point screenSize = this.game.ScreenSize;
            this.powerUpTextures = this.game.ModelPresets["PowerUps"];

            while (this.game.ActualLevel.Config.HudTextColors.Count < this.game.MaxPlayers)
            {
                this.game.ActualLevel.Config.HudTextColors.Add(Color.Black);
            }

            for (int i = 0; i < game.MaxPlayers; i++)
            {
                //this.PowerupImages[i].Visible = (i < activePlayers);
                //if (i % 2 == 0)
                //{
                //    this.PowerupImages[i].Bounds = new Rectangle(dx, this.PowerupImages[i].Bounds.Y, width, width);
                //}
                //else
                //{
                //    this.PowerupImages[i].Bounds = new Rectangle(screenSize.X-dx-width, this.PowerupImages[i].Bounds.Y, width, width);
                //}
                this.PowerupImages[i].Visible = (i < activePlayers);
                this.LabelPlayers[i].Visible = (i < activePlayers);

                this.LabelPlayers[i].Text = this.game.PlayerNames[i].Text;
                this.LabelPlayers[i].TextColor = this.game.ActualLevel.Config.HudTextColors[i];

                this.ScorePlayers[i].TextColor = this.game.ActualLevel.Config.HudTextColors[i];
                this.ScorePlayers[i].Visible = (i < activePlayers);

                //toogle icons, set different icons if needed (based on game type)
                this.Icons[i].Visible = (i < activePlayers);
                if (this.game.GameManager != null)
                {
                    if (this.game.GameManager.PositionFactor == PositionFactors.Lives)
                    {
                        this.Icons[i].Texture = powerUpTextures.Textures[8].Texture;        //TODO : replace 8 with better reference to the image
                    }
                    if (this.game.GameManager.PositionFactor == PositionFactors.Kills)
                    {
                        this.Icons[i].Texture = powerUpTextures.Textures[7].Texture;        //TODO : replace 7 with better reference to the image
                    }
                }
            }
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            if (hud.ContentLoaded == false)
            {
                hud.LoadContent(this.Game.Content);
            }
        }

        /// <summary>
        /// Aktualizuje informace vykreslene v HUDu
        /// </summary>
        /// <param name="gameTime">doba uplynula od posledniho prekresleni</param>
        public override void Update(GameTime gameTime)
        {
            if (game.GameManager.PositionFactor == PositionFactors.Kills)
            {
                this.UpdateKills();
            }
            else
            {
                this.UpdateLives();
            }
            if (this.showHelp)
            {
                this.elapsedTime += gameTime.ElapsedGameTime;
                if (elapsedTime.TotalSeconds > 20 )
                {
                    this.showHelp = false;
                    /// alebo ten druhy
                    for (int i = 0; i < this.helpLabelsJoistick.Length; i++)
                    {
                        this.helpLabelsJoistick[i].Visible = false;
                    }
                }
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// Vykresluje pocet fragu pro vsechny aktivni hrace ve hre
        /// </summary>
        private void UpdateKills()
        {
            for (int i = 0; i < activePlayers; i++)
            {
                this.ScorePlayers[i].Text = game.GameManager.Statistics[i].Kills.ToString();
            }
        }

        /// <summary>
        /// Vykresluje pocet zbylych zivotu pro vsechny aktivni hrace ve hre
        /// </summary>
        private void UpdateLives()
        {
            for (int i = 0; i < activePlayers; i++)
            {
                this.ScorePlayers[i].Text = game.GameManager.Statistics[i].Lives.ToString();
            }
        }

        public override void Draw(GameTime gameTime)
        {
            this.game.SpriteBatch.Begin();
            hud.Draw(this.game.SpriteBatch, Color.White);
            this.game.SpriteBatch.End();
        }
    }
}